作品 Demo 連結: 傳送門
作品目標:輸入關鍵字會自動過濾出相關地區名稱,並且 hightlight 我們所輸入的文字
難易度:★★★☆☆
HTML
<form class="search-form">
<input type="text" class="search" placeholder="City or State">
<ul class="suggestions">
<li>Filter for a city</li>
<li>or a state</li>
</ul>
</form>
會使用到的 CSS
.hl { background:#ffc600; }
初始 JavaScript
const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';
//將 數字自動加上逗點的函數
function numberWithCommas(x){
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ', ');
}
在一開始的 START 檔案中,作者就給了我們 JSON 的連結
第一個步驟就是要將遠端的 JSON 檔案傳存為陣列物件到我們本地的變數中
const cities = [];
fetch(endpoint)
.then(blob => blob.json())
.then(data => cities.push(...data));
因為使用 原生JavaScript 的 AJAX 之後其實會很難維護,
所以在 ES6 時推出了 fetch() 這一個函數!
.then() 這裡是類似 callback 功能
第一個 .then() 是在下載完成後將檔案轉檔成物件
第二個 .then() 是將我們接收到的資料
一個一個的 push() 到 cities 這個陣列變數裡頭。
關於 ... 的部分我還不是很清楚,
目前還查不到,但這邊的作用是將元素不論幾層,
都將其 push() 到 cities 陣列中。
這樣我們的 cities 裡頭就有 1,000 筆美國地區資訊囉!
function findMatches(wordToMatch, cities){
return cities.filter(place => {
const regex = new RegExp(wordToMatch, 'gi')
return place.city.match(regex) || place.state.match(regex);
});
}
創立一個名為 findMatches 的函數
第一個參數為 使用者輸入的文字
第二個參數為我們的資料陣列
我們針對 cities 內容元素一筆一筆去做過濾
使用到我們之前學過的陣列功能 .filter()
RegExp 平時可以只用它特殊的寫法去過濾即可,
只是我們在這裡要過濾的是個變數,
這時候就需要 new 一個 RegExp 出來
後頭的 'gi' 代表的兩個功能
1. 'g':整個 data 都查找,而不是只找到第一個之後就停止
2. 'i':代表不用區分大小寫
最後我們不論是資料裡的 city 屬性 或是 state 屬性,
只要有符合的,通通都回傳
RegExp 相關用法很複雜並不在此次討論範圍,
有興趣的可以上網爬文 =)
function displayMatches(){
const matchArray = findMatches(this.value, cities);
const html = matchArray.map(place => {
const regex = new RegExp(this.value, 'gi');
const cityName = place.city.replace(regex, `<span class="hl">${this.value}</span>`);
const stateName = place.state.replace(regex, `<span class="hl">${this.value}</span>`);
return `
<li>
<span class="name">${cityName}, ${stateName}</span>
<span class="population">${numberWithCommas(place.population)}</span>
</li>
`;
}).join('');
suggestions.innerHTML = html;
}
matchArray 變數以陣列狀態存放第二步函數過濾後的資料
接著我們使用 .map() 遍歷陣列每個元素
再一次的使用到 RegExp
如果資料中如果有我們輸入的文字,
則將其過濾出來用 span.hl 包裹起來,
否則不用包
最後再放入 HTML 公版裡頭後回傳
最後 innerHTML 放入 .suggestion 區塊裡頭做顯示!
numberWithCommas(place.population) 這個函數是作者事先幫我們寫好
使用 RegExp 語法將數字自動加上逗點
這個比較進階,在此作者說可先略過
const searchInput = document.querySelector('.search');
const suggestions = document.querySelector('.suggestions');
searchInput.addEventListener('change', displayMatches);
searchInput.addEventListener('keyup', displayMatches);
這裡我就不多做解釋囉! (偷懶!!! X"P
這是我第一次參加鐵人競賽
最近個人有些私事壓力頗大...
發現鐵人賽要持續下去真的超級難 QAQ
有時候真的會跟自己說幹麻自己找罪受...
在此我要深深的向每位可以把文章寫得超棒
又可以每日穩定量產的鐵人們表達我的敬意!!
大家繼續加油!!!
也希望我的肝可以繼續努力地撐下去!!